package com.example.tourism.service.impl;


import com.example.tourism.mapper.UserMapper;
import com.example.tourism.pojo.Result;
import com.example.tourism.pojo.po.User;
import com.example.tourism.pojo.vo.req.LoginReqVo;
import com.example.tourism.pojo.vo.req.RegisterReqVo;
import com.example.tourism.pojo.vo.req.UserInfoReqVo;
import com.example.tourism.pojo.vo.res.DoubleTokenResVo;
import com.example.tourism.pojo.vo.res.UserInfoResVo;
import com.example.tourism.service.UserService;
import com.example.tourism.utils.TokenUtil;
import com.example.tourism.utils.mail.JavaMailUntil;
import com.example.tourism.utils.mail.SendMail;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

import static com.example.tourism.pojo.Result.error;
import static com.example.tourism.pojo.Result.success;
import static java.time.LocalTime.now;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Result<String> register(RegisterReqVo reqVo) {
        // System.out.println("邮箱加密码"+ email+" \n"+password);
        // 保存用户

        // 1.验证验证码是否正确
        String code = redisTemplate.opsForValue().get(reqVo.getEmail());
        if (code == null) {
            return error(400, "验证码已过期");
        }
        if (!code.equals(reqVo.getCaptcha())) {
            return error(400, "验证码错误");
        }
        // 删除redis中的验证码
        redisTemplate.delete(reqVo.getEmail());

        // 2. 验证邮箱是否存在
        User user = userMapper.selectByEmail(reqVo.getEmail());
        if (user != null) {
            return error(400, "邮箱已注册！");
        }
        // 3. 保存用户
        int result = userMapper.insertUser(reqVo.getEmail(), reqVo.getPassword());
        if (result == 0) {
            return error(400, "注册失败");
        }
        return success("注册成功");
    }

    @Override
    public Result<String> sendVerifyCode(String email) {
        // 检测邮箱是否正确
        if (email == null || !email.matches("^\\w+@\\w+(\\.\\w+)+$")) {
            return error(400, "邮箱格式不正确");
        }
        // 检测邮箱是否存在
        User user = userMapper.selectByEmail(email);
        if (user != null) {
            return error(400, "邮箱已存在");
        }

        // 1. 生成验证码
        String code = JavaMailUntil.generateCode(6);
        System.out.println("验证码：" + code);
        // 2. 发送验证码
        SendMail sendMail = new SendMail(email, code);
        sendMail.sendMineMessage();

        // 3. 保存验证码,使用redis存储起来
        redisTemplate.opsForValue().set(email, code, 3, TimeUnit.MINUTES);

        // 4. 返回结果
        return success("发送验证码成功");
    }

    @Override
    public Result<String> checkVerifyCode(String email, String code) {
        // 1. 获取redis中的验证码
        String redisCode = (String) redisTemplate.opsForValue().get(email);
        if (redisCode == null) {
            return error(400, "验证码已过期");
        }
        if (!redisCode.equals(code)) {
            return error(400, "验证码错误");
        }
        // 2. 删除redis中的验证码
        redisTemplate.delete(email);
        return success("验证码正确");
    }

    @Override
    public Result<DoubleTokenResVo> login(LoginReqVo reqVo, HttpServletResponse response) {
        // 1. 判断用户名和密码是否正确
        User user = userMapper.selectByEmail(reqVo.getEmail());
        if (user == null) {
            return error(400, "用户名错误");
        }
        if (!user.getPassword().equals(reqVo.getPassword())) {
            return error(400, "用户名或密码错误");
        }

        // 2. 返回结果(token)
        String accessToken = TokenUtil.generateAccessToken(String.valueOf(user.getId()), now().toString());
        String refreshToken = TokenUtil.generateRefreshToken(String.valueOf(user.getId()), now().toString());


        response.addHeader("AccessToken", accessToken);
        response.addHeader("RefreshToken", refreshToken);
        DoubleTokenResVo doubleTokenResVo = new DoubleTokenResVo();
        doubleTokenResVo.setAccessToken(accessToken);
        doubleTokenResVo.setRefreshToken(refreshToken);
        return Result.success(doubleTokenResVo);
    }


    public Result<String> refreshToken(String token, HttpServletResponse response) {

        Claims claims;
        try {
            claims = TokenUtil.parseJWT(token);
        } catch (Exception e) {
            // 令牌过期 &
            System.out.println("长token 过期  token为："+token);
            return error(401, "token expired");
        }
        String Id = claims.getId();
        User user = userMapper.selectById(Id);
        if (user != null) {
            // 令牌有效
//            String accessToken = TokenUtil.generateAccessToken(user.getEmail(), now().toString());
//            String refreshToken = TokenUtil.generateRefreshToken(user.getEmail(), now().toString());
            String accessToken = TokenUtil.generateAccessToken(String.valueOf(user.getId()), now().toString());
            String refreshToken = TokenUtil.generateRefreshToken(String.valueOf(user.getId()), now().toString());
            response.addHeader("AccessToken", accessToken);
            response.addHeader("RefreshToken", refreshToken);
            System.out.println("刷新令牌成功");
            return Result.success();
        } else {
            return error(400, "用户不存在");
        }
    }

    @Override
    public Result<UserInfoResVo> getUserInfo(HttpServletRequest request) {
        String Id = (String) request.getAttribute("Id");
        if(Id == null){
            error( 500, "程序出错");
        }
        User user = userMapper.selectById(Id);
        UserInfoResVo  userInfoResVo;
        if (user == null) {
            return error(400, "用户不存在");
        }else {
              userInfoResVo = new UserInfoResVo();
            userInfoResVo.setUsername(user.getUsername());
            userInfoResVo.setEmail(user.getEmail());
            userInfoResVo.setAvatar(user.getAvatar());
            userInfoResVo.setSex(user.getSex());
            LocalDate birthday = user.getBirthday();
            if(birthday == null){
                userInfoResVo.setBirthday("未设置");
            }else {
                userInfoResVo.setBirthday(birthday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            userInfoResVo.setPhone(user.getPhone());
        }

        return success(userInfoResVo);
    }

    @Override
    public Result<String> updateUserInfo(UserInfoReqVo user, HttpServletRequest request) {

        String Id = (String) request.getAttribute("Id");
        // 修改用户信息
        int i = userMapper.updateUserInfo(user,Id);
        if (i == 0) {
            return error(400, "修改失败");
        }
        return success("修改成功");
    }

    @Override
    public Result updateUserAvatar(String id,String avatarUrl) {
        int i = userMapper.updateUserAvatar(id,avatarUrl);
        if (i == 0) {
            return error(400, "修改失败");
        }
        return success("修改成功");
    }

    @Override
    public Result getUserAllInfo(String id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return error(400, "用户不存在");
        }
        user.setPassword("");
        return success(user);
    }

}
